package com.project.template.utils;


import com.project.template.entity.SysUser;
import com.project.template.entity.User;
import com.project.template.service.SysUserService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class JwtUtils {
    private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);

    /**
     * token 过期时间, 单位: 秒. 这个值表示 30 天
     */
    private static final long TOKEN_EXPIRED_TIME = 30L * 24 * 60 * 60 * 1000;

    public static final String SYS_USER_JWT_ID = "sysUserTokenId";
    public static final String USER_JWT_ID = "userTokenId";

    /**
     * jwt 加密解密密钥(可自行填写)
     */
    private static final String JWT_SECRET = "1234567890";

    /**
     * 创建JWT
     */
    public static String createJWT(Map<String, Object> claims, String jwtId, Long time) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        Date now = new Date(System.currentTimeMillis());

        SecretKey secretKey = generalKey();
        long nowMillis = System.currentTimeMillis();

        JwtBuilder builder = Jwts.builder()
                .setClaims(claims)
                .setId(jwtId)
                .setIssuedAt(now)
                .signWith(signatureAlgorithm, secretKey);
        if (time >= 0) {
            long expMillis = nowMillis + time;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }
        return builder.compact();
    }

    /**
     * 验证jwt
     */
    public static Claims verifyJwt(String token) {
        SecretKey key = generalKey();
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(key)
                    .parseClaimsJws(token).getBody();
        } catch (Exception e) {
            logger.error("JWT 验证失败: {}", e.getMessage());
            claims = null;
        }
        return claims;
    }

    /**
     * 由字符串生成加密key
     */
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.getEncoder().encode(JWT_SECRET.getBytes());
        return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
    }

    /**
     * 根据 SysUser 实体生成 token
     */
    public static String generateToken(SysUser sysUser) {
        Map<String, Object> map = new HashMap<>();
        map.put("userId", sysUser.getId());
        map.put("username", sysUser.getUsername());
        map.put("roleType", sysUser.getRoleType());
        map.put("email", sysUser.getEmail());
        return createJWT(map, SYS_USER_JWT_ID, TOKEN_EXPIRED_TIME);
    }

    /**
     * 根据 User 实体生成 token
     */
    public static String generateToken(User user) {
        Map<String, Object> map = new HashMap<>();
        map.put("userId", user.getId());
        map.put("username", user.getUsername());
        return createJWT(map, USER_JWT_ID, TOKEN_EXPIRED_TIME);
    }

    /**
     * 通过 token 获取用户 Id
     */
    public static Integer getUserIdFromToken(String token) {
        Claims claims = verifyJwt(token);
        if (claims != null) {
            return (Integer) claims.get("userId");
        }
        return null;
    }
}